home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / pennmush.000 / pennmush-1.50-p8-linux.tar / pennmush / speech.c < prev    next >
C/C++ Source or Header  |  1993-04-21  |  20KB  |  864 lines

  1. /* speech.c */
  2.  
  3. #include "copyright.h"
  4.  
  5. /* Commands which involve speaking */
  6. #include <ctype.h>
  7. #include <string.h>
  8.  
  9. #include "config.h"
  10. #include "externs.h"
  11. #include "db.h"
  12. #include "interface.h"
  13. #include "match.h"
  14. #include "attrib.h"
  15.  
  16. extern dbref speaker;        /* from game.c */
  17.  
  18. #ifdef FULL_INVIS
  19. const char *spname(thing)
  20.     dbref thing;
  21. {
  22.   /* if FULL_INVIS is defined, dark objects and dark wizards will be
  23.    * Something and Someone, respectively.
  24.    */
  25.  
  26.   if (!Dark(thing))
  27.     return (Name(thing));
  28.   else {
  29.     if (Typeof(thing) != TYPE_PLAYER)
  30.       return ("Something");
  31.     else
  32.       return ("Someone");
  33.   }
  34. }
  35. #else
  36. #define spname(x)      (db[(x)].name)
  37. #endif                /* FULL_INVIS */
  38.  
  39. #ifdef NEVER
  40. const char *reconstruct_message(arg1, arg2)
  41.     const char *arg1;
  42.     const char *arg2;
  43. {
  44.   /* this function is a kludge for regenerating messages split by '='
  45.    * note that it messes up things like "Joe says, "foo == bar"".
  46.    */
  47.  
  48.   static char buf[BUFFER_LEN];
  49.   if (arg2 && *arg2) {
  50.     strcpy(buf, arg1);
  51.     strcat(buf, " = ");
  52.     strcat(buf, arg2);
  53.     return buf;
  54.   } else {
  55.     return arg1;
  56.   }
  57. }
  58. #endif                /* NEVER */
  59.  
  60. void do_say(player, tbuf1)
  61.      dbref player;
  62.      const char *tbuf1;
  63. {
  64.   dbref loc;
  65.  
  66.   if ((loc = getloc(player)) == NOTHING)
  67.     return;
  68.  
  69.   /* notify everybody */
  70.   notify_noecho(player, tprintf("You say, \"%s\"", tbuf1));
  71.   notify_except(db[loc].contents, player,
  72.         tprintf("%s says, \"%s\"", spname(player), tbuf1));
  73. }
  74.  
  75. void do_oemit(player, arg1, arg2)
  76.     dbref player;
  77.     const char *arg1;
  78.     const char *arg2;
  79. {
  80.     dbref who;
  81.     dbref loc;
  82.     char *temp;
  83.     void oemit_notify_except();
  84.  
  85.     if ((temp = (char *)index(arg1, '/')) == NULL) {
  86.     if ((loc = getloc(player)) == NOTHING)
  87.         return;
  88.     init_match(player, arg1, NOTYPE);
  89.     match_neighbor();
  90.     match_me();
  91.     match_player();
  92.     match_absolute();
  93.    } else {
  94.     *temp++ = '\0';
  95.  
  96.     /* first find the room */
  97.     init_match(player, arg1, NOTYPE);
  98.     match_everything();
  99.     if ((loc = noisy_match_result()) == NOTHING)
  100.         return;
  101.  
  102.     /* then find the player */
  103.     init_match_remote(loc, temp, NOTYPE);
  104.     match_remote();
  105.     }
  106.  
  107.     switch (who = match_result()) {
  108.       case NOTHING:
  109.       case AMBIGUOUS:
  110.     who = player;
  111.       default:
  112.     if (who != player)
  113.         notify_noecho(player, arg2);
  114.     oemit_notify_except(db[loc].contents, player, who, arg2);
  115.     }
  116. }
  117.  
  118. void do_whisper(player, arg1, arg2)
  119.     dbref player;
  120.     const char *arg1;
  121.     const char *arg2;
  122. {
  123.   dbref who;
  124.   int key;
  125.   const char *gap;
  126.   init_match(player, arg1, TYPE_PLAYER);
  127.   match_neighbor();
  128.   match_possession();
  129.   match_container();
  130.   match_me();
  131.   if (Wizard(player)) {
  132.     match_absolute();
  133.     match_player();
  134.   }
  135.   switch (who = match_result()) {
  136.     case NOTHING:
  137.       notify(player, "Whisper to whom?");
  138.       break;
  139.     case AMBIGUOUS:
  140.       notify(player, "I don't know who you mean!");
  141.       break;
  142.     default:
  143.       gap = " ";
  144.       switch (*arg2) {
  145.       case SEMI_POSE_TOKEN:
  146.     gap = "";
  147.       case POSE_TOKEN:
  148.     key = 1;
  149.     arg2 = arg2 + 1;
  150.     break;
  151.       default:
  152.     key = 2;
  153.     break;
  154.       }
  155.       switch (key) {
  156.       case 1:
  157.     notify(player, tprintf("%s senses, \"%s%s%s\"", db[who].name,
  158.       db[player].name, gap, arg2));
  159.     notify(who, tprintf("You sense: %s%s%s", db[player].name, gap, arg2));
  160.     break;
  161.       case 2:
  162.         notify(player,
  163.          tprintf("You whisper, \"%s\" to %s.", arg2, db[who].name));
  164.         notify(who,
  165.          tprintf("%s whispers, \"%s\"", db[player].name, arg2));
  166.         break;
  167.       }
  168.       break;
  169.   }
  170. }
  171.  
  172. void do_pemit(player, arg1, arg2, silent)
  173.      dbref player;
  174.      const char *arg1;
  175.      const char *arg2;
  176.      int silent;
  177. {
  178.   dbref who;
  179.  
  180.   init_match(player, arg1, NOTYPE);
  181.   match_neighbor();
  182.   match_possession();
  183.   match_container();
  184.   match_me();
  185.   match_here();
  186.   match_player();
  187.   match_absolute();
  188.   switch (who = match_result()) {
  189.   case NOTHING:
  190.     notify(player, "I don't see that player here.");
  191.     break;
  192.   case AMBIGUOUS:
  193.     notify(player, "I don't know who you mean!");
  194.     break;
  195.   default:
  196.     if (Typeof(who) != TYPE_PLAYER && Typeof(who) != TYPE_THING) {
  197.       notify(player, "Only players and things can hear @pemits.");
  198.       break;
  199.     }
  200.     if ((player != who) &&
  201.     (Haven(who) ||
  202.      ((Typeof(who) == TYPE_PLAYER) && 
  203.       !eval_boolexp(player, db[who].usekey, who, 0, USELOCK)))) {
  204.       notify(player,tprintf("I'm sorry, but %s wishes to be left alone now.",
  205.                 db[who].name));
  206.       return;
  207.     }
  208.     if (!silent)
  209.       notify(player,
  210.          tprintf("You pemit \"%s\" to %s.", arg2, db[who].name));
  211.     if (Nospoof(who)) {
  212. #ifdef PARANOID_NOSPOOF
  213.       notify(who, tprintf("[%s(#%d)->%s] %s", db[player].name, player,
  214.               db[who].name, arg2));
  215. #else
  216.       notify(who,
  217.         tprintf("[%s->%s] %s", db[player].name, db[who].name, arg2));
  218. #endif
  219.     } else {
  220.       notify(who,
  221.         tprintf("%s", arg2));
  222.     }
  223.     break;
  224.   }
  225. }
  226.  
  227. void do_pose(player, tbuf1, space)
  228.      dbref player;
  229.      const char *tbuf1;
  230.      int space;
  231. {
  232.   dbref loc;
  233.  
  234.   if ((loc = getloc(player)) == NOTHING)
  235.     return;
  236.  
  237.   /* notify everybody */
  238.   if(!space)
  239.     notify_except(db[loc].contents, NOTHING,
  240.           tprintf("%s %s", spname(player), tbuf1));
  241.   else
  242.     notify_except(db[loc].contents, NOTHING,
  243.           tprintf("%s%s", spname(player), tbuf1));
  244. }
  245.  
  246. void do_wall(player, message, privs, key)
  247.     dbref player;
  248.     const char *message;
  249.     int privs;
  250.     int key;
  251. {
  252.     /* privs is 0 for wizard wizwall, 1 for royalty-wizard wizwall,
  253.      * 2 is for general wall
  254.      */
  255.  
  256.     const char *gap, *prefix;
  257.     int mask;
  258.  
  259.     /* command is only available to wizards and royalty */
  260.     if (!Hasprivs(player)) {
  261.     notify(player, "What makes you think someone wants to listen to you?");
  262.     return;
  263.     }
  264.  
  265.     /* only @rwall is available to royalty */
  266.     if ((privs != 1) && !Wizard(player)) {
  267.     notify(player,
  268.            "Posing as a wizard could be hazardous to your health.");
  269.     return;
  270.     }
  271.  
  272.     /* put together the message and figure out what type it is */
  273.     gap = " ";
  274.     switch(*message) {
  275.       case SAY_TOKEN:
  276.     key = 1;
  277.     message = message + 1;
  278.     break;
  279.       case SEMI_POSE_TOKEN:
  280.     gap = "";
  281.       case POSE_TOKEN:
  282.     key = 2;
  283.     message = message + 1;
  284.     break;
  285.     }
  286.  
  287.     if (privs == 0) {
  288.     /* to wizards only */
  289.     mask = WIZARD;
  290.     prefix = "Broadcast";
  291.     }
  292. #ifdef ROYALTY_FLAG
  293.     else if (privs == 1) {
  294.     /* to wizards and royalty */
  295.     mask = WIZARD | ROYALTY;
  296.     prefix = "Admin";
  297.     }
  298. #endif                /* ROYALTY_FLAG */
  299.     else {
  300.     /* to everyone */
  301.     mask = 0;
  302.     prefix = "Announcement";
  303.     }
  304.  
  305.     /* broadcast the message */
  306.     switch(key) {
  307.       case 2:
  308.     raw_broadcast(mask, "%s: %s%s%s", prefix, db[player].name, gap,
  309.               message);
  310.     break;
  311.       case 3:
  312.     raw_broadcast(mask, "%s [%s]: %s", prefix, db[player].name, message);
  313.     break;
  314.       default:
  315.     raw_broadcast(mask, "%s: %s %s, \"%s\"", prefix, db[player].name,
  316.               ((privs != 2) ? "says" : "shouts"), message);
  317.     }
  318.  
  319.     /* log it if necessary */
  320.     if ((privs == 2) || (options.log_walls && (privs == 0))) {
  321.     switch (key) {
  322.       case 2:
  323.         do_log(LT_WIZ, player, NOTHING, "(MSG/%s) %s%s%s",
  324.            (privs == 0) ? "wiz" : "all", Name(player), gap, message);
  325.         break;
  326.       default:
  327.         do_log(LT_WIZ, player, NOTHING, "(MSG/%s) %s",
  328.            (privs == 0) ? "wiz" : "all", message);
  329.         break;
  330.     }
  331.     }
  332. }
  333.  
  334.  
  335. void do_page(player, arg1, arg2)
  336.     dbref player;
  337.     const char *arg1;
  338.     const char *arg2;
  339. {
  340.   dbref target;
  341.   char *message;
  342.   const char *gap;
  343.   int key;
  344.   char tbuf[BUFFER_LEN];
  345.  
  346.   if (!*arg1 && (!arg2 || !*arg2)) {
  347.     if (Typeof(player) == TYPE_PLAYER) {
  348.       if (db[player].parent == NOTHING) {
  349.     notify(player, "You haven't paged anyone since connecting.");
  350.       } else {
  351.     notify(player,
  352.            tprintf("You last paged %s.", db[db[player].parent].name));
  353.       }
  354.     } else
  355.       notify(player, "No record is being kept of your pages.");
  356.     return;
  357.   }
  358.   if (Haven(player))
  359.       notify(player, "You are set HAVEN and cannot receive pages.");
  360.  
  361.   if (!arg2 || !*arg2) {
  362.     message = (char *) arg1;
  363.     if (Typeof(player) == TYPE_PLAYER)
  364.       target = db[player].parent;
  365.     else
  366.       target = NOTHING;
  367.   } else {
  368.     message = (char *) arg2;
  369.     if (!*arg1) {
  370.       if (Typeof(player) == TYPE_PLAYER)
  371.     target = db[player].parent;
  372.       else
  373.     target = NOTHING;
  374.     } else if ((target = lookup_player(arg1)) == NOTHING) {
  375.       if (!*arg2) {
  376.     if (Typeof(player) == TYPE_PLAYER)
  377.       target = db[player].parent;
  378.     else
  379.       target = NOTHING;
  380.         message = (char *) arg1;
  381.       } else {
  382.         target = short_page(arg1);
  383.       }
  384.     }
  385.   }
  386.   if (target == NOTHING) {
  387.     notify(player, "I can't find who you're trying to page.");
  388.     return;
  389.   } else if (target == AMBIGUOUS) {
  390.     notify(player, "I'm not sure who you want to page!");
  391.     return;
  392.   } else if (!(Toggles(target) & PLAYER_CONNECT) ||
  393.              (Dark(target) && Haven(target))) {
  394.     page_return(player, target, "Away", "AWAY",
  395.       "That player is not connected.");
  396.     return;
  397.   } else if (Haven(target)) {
  398.     page_return(player, target, "Haven", "HAVEN",
  399.       "That player is not accepting any pages.");
  400.     return;
  401.   } else if (!eval_boolexp(player, db[target].usekey, 
  402.                target, 0, USELOCK)) {
  403.     page_return(player, target, "Haven", "HAVEN",
  404.       "That player is not accepting your pages.");
  405.     return;
  406.   } if (!payfor(player, PAGE_COST)) {
  407.     notify(player, tprintf("You don't have enough %s.", MONIES));
  408.     return;
  409.   }
  410.  
  411.   if (Typeof(player) == TYPE_PLAYER)
  412.     db[player].parent = target;
  413.  
  414.   gap = " ";
  415.   switch (*message) {
  416.     case SEMI_POSE_TOKEN:
  417.       gap = "";
  418.     case POSE_TOKEN:
  419.       key = 1;
  420.       message = message + 1;
  421.       break;
  422.     case NULL:
  423.       key = 2;
  424.       break;
  425.     default:
  426.       key = 3;
  427.       break;
  428.   }
  429.  
  430.   /* this is a hack: truncate the message if it's going to overflow
  431.    * the tprintf buffer.
  432.    */
  433.   if (strlen(message) > BUFFER_LEN - 32)
  434.     message[BUFFER_LEN - 32] = '\0';
  435.  
  436.   switch (key) {
  437.   case 1:
  438.     sprintf(tbuf, "From afar, %s%s%s", db[player].name, gap, message);
  439.     notify(player, tprintf("Long distance to %s: %s%s%s", db[target].name,
  440.                db[player].name, gap, message));
  441.     break;
  442.   case 2:
  443.     sprintf(tbuf, "You sense that %s is looking for you in %s",
  444.         db[player].name, db[getloc(player)].name);
  445.     notify(player, tprintf("You have notified %s of your location.", 
  446.                db[target].name));
  447.     break;
  448.   case 3:
  449.     sprintf(tbuf, "%s pages: %s", db[player].name, message);
  450.     notify(player, tprintf("You paged %s with '%s'.", db[target].name,
  451.                message));
  452.     break;
  453.   }
  454.   if (Typeof(player) != TYPE_PLAYER && Nospoof(target))
  455.     notify(target, tprintf("[#%d] %s", player, tbuf));
  456.   else
  457.     notify(target, tbuf);
  458.   page_return(player, target, "Idle", "IDLE", NULL);
  459.   return;
  460. }
  461.  
  462. void esnotify(player, msg, sender)
  463.     dbref player;
  464.     const char *msg;
  465.     dbref sender;
  466. {
  467.   if (player < 0 || player >= db_top) return;
  468.  
  469.   if (Nospoof(player)) {
  470. #ifdef PARANOID_NOSPOOF
  471.     notify_noecho(player, 
  472.           tprintf("[%s(#%d)] %s", spname(sender), sender, msg));
  473. #else
  474.     notify_noecho(player, tprintf("[%s:] %s", spname(sender), msg));
  475. #endif
  476.   } else {
  477.     notify_noecho(player, msg);
  478.   }
  479. }
  480.  
  481. int filter_found(thing, msg, flag)
  482.      dbref thing;
  483.      const char *msg;
  484.      int flag;            /* 0 for @filter, 1 for @infilter */
  485. {
  486.   /* check to see if the message matches the filter pattern on thing */
  487.  
  488.   char *filter;
  489.   ATTR *a;
  490.   char *p;
  491.   char *temp;            /* need this so we don't leak memory     
  492.                                  * by failing to free the storage
  493.                  * allocated by safe_uncompress
  494.                  */
  495.  
  496.   int i;
  497.   int matched = 0;
  498.  
  499.   if (!flag)
  500.     a = atr_get(thing, "FILTER");
  501.   else
  502.     a = atr_get(thing, "INFILTER");
  503.   if (!a)
  504.     return matched;
  505.  
  506.   filter = safe_uncompress(a->value);
  507.   temp = filter;
  508.  
  509.   for (i = 0; (i < MAX_ARG) && !matched; i++) {
  510.     p = parse_to(&filter, ',', 0);
  511.     if (p)
  512.       matched = wild_match(p, msg);
  513.   }
  514.  
  515.   free(temp);
  516.   return matched;
  517. }
  518.  
  519. void propagate_sound(thing, msg)
  520.      dbref thing;
  521.      const char *msg;
  522. {
  523.     /* pass a message on, for AUDIBLE, prepending a prefix, unless the
  524.      * message matches a filter pattern.
  525.      */
  526.  
  527.     char *prefix, *bp;
  528.     char tbuf1[BUFFER_LEN];
  529.     ATTR *a;
  530.     dbref player;
  531.     dbref loc = db[thing].location;
  532.  
  533.     if (!GoodObject(loc))
  534.     return;
  535.  
  536.     /* check to see that filter doesn't suppress message */
  537.     if (filter_found(thing, msg, 0))
  538.     return;
  539.   
  540.     /* figure out the prefix */
  541.  
  542.     a = atr_get(thing, "PREFIX");
  543.  
  544.     if (!a) {
  545.     prefix = (char *) malloc(BUFFER_LEN + 1);
  546.     if (Typeof(thing) == TYPE_EXIT)
  547.         sprintf(prefix, "From %s,", Name(Exits(thing)));
  548.     else
  549.         sprintf(prefix, "From %s,", Name(thing));
  550.     } else {
  551.     strcpy(tbuf1, uncompress(a->value));
  552.     prefix = exec(thing, speaker, EV_STRIP | EV_FCHECK, tbuf1);
  553.     }
  554.  
  555.     bp = tbuf1;
  556.     safe_str(prefix, tbuf1, &bp);
  557.     safe_chr(' ', tbuf1, &bp);
  558.     safe_str(msg, tbuf1, &bp);
  559.     *bp = '\0';
  560.  
  561.     /* Exits pass the message on to things in the next room.
  562.      * Objects pass the message on to the things outside.
  563.      * Don't tell yourself your own message.
  564.      */
  565.  
  566.     if (Typeof(thing) == TYPE_EXIT) {
  567.     DOLIST(player, db[loc].contents)
  568.         notify(player, tbuf1);
  569.     } else {
  570.     DOLIST(player, db[loc].contents) {
  571.         if (player != thing)
  572.         notify(player, tbuf1);
  573.     }
  574.     }
  575.  
  576.     free(prefix);
  577. }
  578.  
  579. void notify_except(first, exception, msg)
  580.     dbref first;
  581.     dbref exception;
  582.     const char *msg;
  583. {
  584.   dbref loc = db[first].location;
  585.   dbref e;
  586.   char tbuf1[BUFFER_LEN];
  587.  
  588.   if(first < 0 || first >= db_top)
  589.     return;
  590.   if (loc != exception)
  591.     notify_noecho(loc, msg);
  592.   DOLIST(first, first) {
  593.     if (first != exception) {
  594.       notify_noecho(first, msg);
  595.     }
  596.   }
  597.  
  598.   /* now do AUDIBLE stuff */
  599.   if (Audible(loc)) {
  600.     if (Typeof(loc) == TYPE_ROOM) {
  601.       /* the strcpy is necessary to prevent choking in propagate_sound
  602.        * when msg is an array of char and not a char * in the calling
  603.        * function. Yes, this is ugly and stupid. It works. Kinda.
  604.        */
  605.       strcpy(tbuf1, msg);
  606.       DOLIST(e, db[loc].exits) {
  607.     if (Audible(e))
  608.       propagate_sound(e, tbuf1);
  609.       }
  610.     } else if (loc != exception) {
  611.       strcpy(tbuf1, msg);
  612.       propagate_sound(loc, tbuf1);
  613.     }
  614.   }
  615. }
  616.  
  617. void emit_notify_except(first, exception, msg)
  618.     dbref first;
  619.     dbref exception;
  620.     const char *msg;
  621. {
  622.   dbref loc = db[first].location;
  623.   dbref e;
  624.   char tbuf1[BUFFER_LEN];
  625.  
  626.   if(first < 0 || first >= db_top)
  627.     return;
  628.   if (loc != exception)
  629.     esnotify(loc, msg, exception);
  630.   DOLIST(first, first) {
  631.     if (first != exception) {
  632.       esnotify(first, msg, exception);
  633.     }
  634.   }
  635.  
  636.   /* do AUDIBLE stuff */
  637.   if (Audible(loc)) {
  638.     if (Typeof(loc) == TYPE_ROOM) {
  639.       /* see notify_except for explanation of why strcpy is needed */
  640.       strcpy(tbuf1, msg);
  641.       DOLIST(e, db[loc].exits) {
  642.     if (Audible(e))
  643.       propagate_sound(e, tbuf1);
  644.       }
  645.     } else if (loc != exception) {
  646.       strcpy(tbuf1, msg);
  647.       propagate_sound(loc, tbuf1);
  648.     }
  649.   }
  650. }
  651.  
  652. void notify_except2(first, exc1, exc2, msg)
  653.     dbref first;
  654.     dbref exc1;
  655.     dbref exc2;
  656.     const char *msg;
  657. {
  658.   dbref loc = db[first].location;
  659.   dbref e;
  660.   char tbuf1[BUFFER_LEN];
  661.  
  662.   if(first < 0 || first >= db_top)
  663.     return;
  664.   if ((loc != exc1) && (loc != exc2))
  665.     notify_noecho(loc, msg);
  666.   DOLIST(first, first) {
  667.     if (first != exc1 && first != exc2) {
  668.       notify_noecho(first, msg);
  669.     }
  670.   }
  671.  
  672.   /* now do AUDIBLE stuff */
  673.   if (Audible(loc)) {
  674.     if (Typeof(loc) == TYPE_ROOM) {
  675.       /* see notify_except for explanation of why strcpy is necessary */
  676.       strcpy(tbuf1, msg);
  677.       DOLIST(e, db[loc].exits) {
  678.     if (Audible(e))
  679.       propagate_sound(e, tbuf1);
  680.       }
  681.     } else if ((loc != exc1) && (loc != exc2)) {
  682.       strcpy(tbuf1, msg);
  683.       propagate_sound(loc, tbuf1);
  684.     }
  685.   }
  686. }
  687.  
  688. void oemit_notify_except(first, exc1, exc2, msg)
  689.     dbref first;
  690.     dbref exc1;
  691.     dbref exc2;
  692.     const char *msg;
  693. {
  694.   dbref loc = db[first].location;
  695.   dbref e;
  696.   char tbuf1[BUFFER_LEN];
  697.  
  698.   if(first < 0 || first >= db_top)
  699.     return;
  700.   if ((loc != exc1) && (loc != exc2))
  701.     esnotify(loc, msg, exc1);
  702.   DOLIST(first, first) {
  703.     if (first != exc1 && first != exc2) {
  704.       esnotify(first, msg, exc1);
  705.     }
  706.   }
  707.  
  708.   /* do AUDIBLE stuff */
  709.   if (Audible(loc)) {
  710.     if (Typeof(loc) == TYPE_ROOM) {
  711.       /* see notify_except for explanation of why strcpy is needed */
  712.       strcpy(tbuf1, msg);
  713.       DOLIST(e, db[loc].exits) {
  714.     if (Audible(e))
  715.       propagate_sound(e, tbuf1);
  716.       }
  717.     } else {
  718.       strcpy(tbuf1, msg);
  719.       propagate_sound(loc, tbuf1);
  720.     }
  721.   }
  722. }
  723.  
  724. void do_think(player, message)
  725.     dbref player;
  726.     const char *message;
  727. {
  728.   /* privately tell yourself a message */
  729.  
  730.   /* notify the player only, with no special fanfare */
  731.   notify(player, tprintf("%s", message));
  732. }
  733.  
  734.  
  735. void do_emit(player, tbuf1)
  736.     dbref player;
  737.     const char *tbuf1;
  738. {
  739.   dbref loc;
  740.  
  741.   if ((loc = getloc(player)) == NOTHING)
  742.     return;
  743.  
  744.   /* notify everybody */
  745.   notify_noecho(player, tprintf("%s", tbuf1));
  746.   emit_notify_except(db[loc].contents, player, tbuf1);
  747. }
  748.  
  749. void do_remit(player, arg1, arg2)
  750.     dbref player;
  751.     const char *arg1;
  752.     const char *arg2;
  753. {
  754.   dbref room;
  755.   const char *rmno;
  756.  
  757.   init_match(player, arg1, NOTYPE);
  758.   match_here();
  759.   match_absolute();
  760.   match_neighbor();
  761.   match_me();
  762.   match_player();
  763.   match_exit();
  764.  
  765.   switch (room = match_result()) {
  766.     case NOTHING:
  767.     case AMBIGUOUS:
  768.       notify(player, "I can't find that.");
  769.       break;
  770.     default:
  771.       if (Typeof(room) == TYPE_EXIT) {
  772.     notify(player, "There can't be anything in that!");
  773.     break;
  774.       }
  775.       if ((Typeof(room) == TYPE_PLAYER) && 
  776.       (Haven(room) || 
  777.        !eval_boolexp(player, db[room].usekey, room, 0, USELOCK))) {
  778.     notify(player,tprintf("I'm sorry, but %s wishes to be left alone now.",
  779.                   db[room].name));
  780.     break;
  781.       }
  782.  
  783.       rmno = unparse_object(player, room);
  784.       notify(player,
  785.         tprintf("You remit, \"%s\" in %s", arg2, rmno));
  786.       oemit_notify_except(db[room].contents, player, room, arg2);
  787.   }
  788. }
  789.  
  790. void do_lemit(player, tbuf1)
  791.   dbref player;
  792.   const char *tbuf1;
  793. {
  794.   /* give a message to the "absolute" location of an object */
  795.  
  796.   dbref room;
  797.   int rec = 0;
  798.  
  799.   /* only players and things may use this command */
  800.   if (!Mobile(player))
  801.     return;
  802.  
  803.   /* prevent infinite loop if player is inside himself */
  804.   if (((room = db[player].location) == player) || !GoodObject(room)) {
  805.     notify(player, "Invalid container object.");
  806.     fprintf(stderr, "** BAD CONTAINER **  #%d is inside #%d.\n",
  807.         player, room);
  808.     return;
  809.   }
  810.   while ((Typeof(room) != TYPE_ROOM) && (rec < 15)) {
  811.     room = db[room].location;
  812.     rec++;
  813.   }
  814.   if (rec > 15) {
  815.     notify(player, "Too many containers.");
  816.     return;
  817.   } else {
  818.     notify(player, tprintf("You lemit: \"%s\"", tbuf1));
  819.     oemit_notify_except(db[room].contents, player, room, tbuf1);
  820.   }
  821. }
  822.  
  823. void do_zemit(player, arg1, arg2)
  824.      dbref player;
  825.      const char *arg1;
  826.      const char *arg2;
  827. {
  828.   const char *where;
  829.   dbref zone;
  830.   dbref room;
  831.  
  832.   init_match(player, arg1, NOTYPE);
  833.   match_absolute();
  834.  
  835.   switch (zone = match_result()) {
  836.   case NOTHING:
  837.   case AMBIGUOUS:
  838.     notify(player, "Invalid zone.");
  839.     return;
  840.   default:
  841.     if (!controls(player, zone)) {
  842.       notify(player, "Permission denied.");
  843.       return;
  844.     }
  845.     /* this command is computationally expensive */
  846.     if (!payfor(player, FIND_COST)) {
  847.       notify(player, "Sorry, you don't have enough money to do that.");
  848.       return;
  849.     }
  850.  
  851.     where = unparse_object(player, zone);
  852.     notify(player,
  853.        tprintf("You zemit, \"%s\" in zone %s", arg2, where));
  854.  
  855.     /* walk the database, giving the message to the contents of all
  856.      * rooms that are zoned to the specified zone.
  857.      */
  858.     for (room = 0; room < db_top; room++)
  859.       if ((getzone(room) == zone) && (Typeof(room) == TYPE_ROOM))
  860.     oemit_notify_except(db[room].contents, player, room, arg2);
  861.   }
  862. }
  863.  
  864.